/**
 * @file ros_can_driver.h
 * @author circleup (circleup@foxmail.com)
 * @brief LCCAN 官方 SDK 封装文件，使其在 ROS 下更容易被使用
 * @version v2.1
 * @date 2020-06-25
 * 
 * @copyright Copyright (c) 2020
 * 
 */

#ifndef _ROS_CAN_DRIVER_H_
#define _ROS_CAN_DRIVER_H_

#include "ICANCmd.h"

/**
 * @brief 下位机 CAN 协议按 bit 定义
 * 
 */

typedef struct {
    BYTE VCU_GEAR_REQ:1;        ///< 主动换挡请求(默认为1)
    BYTE VCU_NULL_1:2;          ///< 占位，值无意义
    BYTE VCU_BREAK_REQ:1;       ///< 主动制动请求(默认为1)
    BYTE VCU_STR_REQ:1;         ///< 主动转向请求(默认为1)
    BYTE VCU_PED_REQ:1;         ///< 主动加速请求
    BYTE VCU_MODE:2;            ///< 工作模式

    BYTE VCU_NULL_2:8;          ///< 占位，值无意义

    BYTE VCU_PED_VALUE;         ///< 油门开度值

    BYTE VCU_STR_ANGLE_H;       ///< （高八位）主动转向角度，报文 =（ 实际转角 + 550 ）x 10

    BYTE VCU_NULL_3:2;          ///< 占位，值无意义
    BYTE VCU_STR_ANGLE_L:6;     ///< （低六位）主动转向角度，报文 =（ 实际转角 + 550 ）x 10

    BYTE VCU_BREAK_VALUE;       ///< 主动制动相对位置

    BYTE VCU_NULL_4:4;          ///< 占位，值无意义
    BYTE VCU_GEAR_VALUE:4;      ///< 目标档位值：R-0x0、N-0x1、D-0x2

    BYTE VCU_NULL_5:8;          ///< 占位，值无意义
} VCU_FRAME_DATA;

/// LCCAN 设备全局句柄
extern DWORD g_devicehandle;

#define __countof(a)  (sizeof(a)/sizeof(a[0]))

#define     DEF_CAR_MESSAGE_FREQ    50      ///< 控制指令发送频率
#define     DEF_CAN_CHANNEL_SELECT  DEF_CAN_CHANNEL_0   ///< 使用的 CAN 通道
#define     DEF_DEV_INDEX           0       ///< 设备索引，从 0 开始
#define     DEF_CAN_CHANNEL_0       0       ///< CAN 0
#define     DEF_CAN_CHANNEL_1       1       ///< CAN 1
#define     DEF_SEND_TYPE           0       ///< CAN 发送类型,0 - 正常发送;1 - 单次发送;2 - 自发自收;3 - 单次自发自收
#define     DEF_SEND_ID             0x238   ///< 发送帧 ID
#define     DEF_RECEIVE_ID          0x240   ///< 接受帧 ID

/**
 * @brief VCU 数据格式化输出
 * 
 */
void vcu_frame_data_format_out(void);

/**
 * @brief VCU 数据格式化输出，CAN_DataFrame 格式重载
 * 
 * @param param 格式化输出结构体指针
 */
void vcu_frame_data_format_out(CAN_DataFrame *param);

/**
 * @brief LCCAN 初始化函数，获取全局句柄
 * 
 * @return DWORD 返回 0 表示失败
 */
DWORD LCCANInit(void);

/**
 * @brief 选择一个通道进行数据传输，具体需要看 ros_can_driver.h 宏定义
 * 
 * @return DWORD 返回 0 表示失败 
 */
DWORD LCCANChanleStart(void);

/**
 * @brief CAN 数据发送函数
 * 
 * @param param 发送数据结构体指针
 */
void Send(CAN_DataFrame *param);

#endif